/**
 * 
 */
package ro.dta.idbi.model;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.filechooser.FileFilter;

import org.w3c.dom.Node;

import ro.dta.idbi.interfaces.ISaveStrategy;

import com.mxgraph.io.mxCodec;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxUtils;

/**
 * XML save strategy, used to save a graph as an XML file
 * 
 * @author Tudor Dobrila
 * 
 */
public class SaveStrategyXml implements ISaveStrategy {

	@Override
	public String getExtension() {
		return ".xml";
	}

	@Override
	public FileFilter getFileFilter() {
		return new XmlFilter();
	}

	@Override
	public void save(mxGraphComponent graphComponent, mxCodec codec, String path) throws IOException {
		final String xml = exportXml(graphComponent, codec);
		FileOutputStream stream;
		stream = new FileOutputStream(path);
		final BufferedOutputStream bos = new BufferedOutputStream(stream);
		bos.write(xml.getBytes());
		bos.close();
		stream.close();
	}

	/**
	 * Export a graph to XML
	 * 
	 * @param graphComponent
	 *            Graph component holding the graph to be exported
	 * @return Graph as XML text
	 */
	public static String exportXml(final mxGraphComponent graphComponent, mxCodec codec) {
		return mxUtils.getXml(exportXml(graphComponent.getGraph().getModel(), codec));
	}

	/**
	 * Export a graph to XML
	 * 
	 * @param graphModel
	 *            Model of the graph being exported
	 * @param codec
	 *            Codec used to save the strategy, depends on the metamodel of
	 *            the schema
	 * @return Graph model as XML text
	 */
	public static Node exportXml(final mxIGraphModel graphModel, mxCodec codec) {
		return codec.encode(graphModel);
	}

	/**
	 * Filter used to show only XML files in the JFileChooser
	 * 
	 * @author Tudor Dobrila
	 * 
	 */
	static class XmlFilter extends FileFilter {

		@Override
		public boolean accept(final File file) {
			boolean result = false;
			if (file.isDirectory()) {
				result = true;
			} else {
				final int dotPos = file.getName().lastIndexOf(".");
				if (dotPos != -1) {
					final String extension = file.getName().substring(dotPos).toLowerCase();

					if (".xml".equals(extension)) {
						result = true;
					}
				}
			}

			return result;
		}

		@Override
		public String getDescription() {
			return "XML files (.xml)";
		}

	}

}
